Library Management

The notion of program library is seen justifiably as one of the fundamental contributions of Ada to software engineering. The library guarantees that type safety is maintained across compilations, and prevents the construction of inconsistent systems by excluding obsolete units. In all Ada compilers to date, the library is a complex structure that holds intermediate representations of compiled units, information about dependences between compiled units, symbol tables, etc. The ARM strongly suggests that such a structure is mandatory, but in fact a monolithic library is not required to implement rigorously the semantics of separate compilation. Furthermore, the monolithic library approach is ill-adapted to multi-language systems, and has been responsible for some of the awkwardess of interfacing Ada to other languages.

We have chosen a completely different approach in GNAT. The library itself is implicit, and object files depend only on the sources used to compile them, and not on other objects. There are no intermediate representations of compiled units, so that the declarations of the units appearing in the context clause of a given compilation are always analyzed anew. Dependency information is kept directly in the object files, and amounts to a few hundred bytes per unit. The binder can be used to verify the consistency of a system before linking, and is also used to determine the order of elaboration. Given the speed of the front-end, our approach is no less efficient than the conventional library mechanism, and has three important advantages over it:

  1. Compilation of an Ada unit is identical to compilation of a module or file in another language: the result of the compilation of one source is one object file, period.

  2. Given that object files only depend on sources, not on other objects, there is no longer a required order of compilation. All the components of a system can be compiled in any order. Only the modification of a source program may obsolete a compiled unit. A well-known dreaded phenomenon of previous Ada systems, namely the accidental recompilation of one unit that obsoletes a slew of other units in the library, even when the source is unchanged, is thus avoided completely.

  3. Inlining works in a much more flexible way than in normal compilers. Given that compiling, and thus inlining, is always done from the source, there is no requirement that the entities to be inlined should be compiled first. It is even possible for two bodies to inline functions defined in each other, without fear of circularities.

It is gratifying that this flexible model is fully conformant with the prescribed semantics given in the ARM, and at the same time confortable for programmers used to the behavior of <#835#>make<#835#> and similar tools. The GNAT model simplifies the construction of multi-language programs and makes Ada look more familiar to programmers in other languages.